﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using System.Data;
using MWPreprocess;
using MWPCA;
using MWDataMining;
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;


namespace Gene_Explorer_Server
{
    class GeneExprData
    {
        private double[,] data;
        private double[,] mainGroup;
        private String[] name;
        private int ndata;
        private int ndim;
        private int nclass;
        public GeneExprData()
        {
            data = null ;
            mainGroup = null ;
            name = null;
            ndata = 0;
            ndim = 0;
            nclass = 0;
        }
        public double[,] getData()
        {
            return data;
        }
        public void setData(double[,] d)
        {
            data = d;
        }
        public double[,] getMainGroup()
        {
            return mainGroup;
        }
        public void setMainGroup(double[,] m)
        {
            mainGroup = m;
        }
        public String[] getName()
        {
            return name;
        }
        public void setName(String[] n)
        {
            name = n;
        }
        public int getDataNum()
        {
            return ndata;
        }
        public void setDataNum(int d)
        {
            ndata = d;
        }
        public int getDataDimension()
        {
            return ndim;
        }
        public void setDataDimension(int d)
        {
            ndim = d;
        }
        public int getClassNum()
        {
            return nclass;
        }
        public void setClassNum(int ncl)
        {
            nclass = ncl;
        }
        public void excelReader(string filePath, string sheetName, string dataReg, string mainGroupReg, string nameReg, int ncl)
        {
            string StrConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + filePath + ";Extended Properties='Excel 8.0;HDR=NO'";
            OleDbConnection MyConn = new OleDbConnection(StrConn);
            MyConn.Open();
            string StrCmdData = "select * from [" + sheetName + "$" + dataReg + "]";
            string StrCmdMainGroup = "select * from [" + sheetName + "$" + mainGroupReg + "]";
            string StrCmdName = "select * from [" + sheetName + "$" + nameReg + "]";
            OleDbDataAdapter MyCommandData = new OleDbDataAdapter(StrCmdData, MyConn);
            OleDbDataAdapter MyCommandMainGroup = new OleDbDataAdapter(StrCmdMainGroup, MyConn);
            OleDbDataAdapter MyCommandName = new OleDbDataAdapter(StrCmdName, MyConn);
            DataSet Ds = new DataSet();
            MyCommandData.Fill(Ds,"Data");
            MyCommandMainGroup.Fill(Ds, "MainGroup");
            MyCommandName.Fill(Ds, "name");
            DataTable DtData = Ds.Tables["Data"];
            DataTable DtMainGroup = Ds.Tables["MainGroup"];
            DataTable Dtname = Ds.Tables["name"];
            ndata = DtData.Rows.Count;
            ndim = DtData.Columns.Count;
            nclass = ncl;
            data = new double[ndata, ndim];
            mainGroup = new double[ndata, 1];
            name = new String[ndata];
            for (int i = 0; i < ndata; i++)
            {
                for (int j = 0; j < ndim; j++)
                {
                    data[i, j] = (double)DtData.Rows[i][j];
                }
            }
            for (int i = 0; i < ndata; i++)
            {
                mainGroup[i, 0] = (double)DtMainGroup.Rows[i][0];
                
            }
            for (int i = 0; i < ndata; i++)
            {
                name[i] = (String)Dtname.Rows[i][0];

            }

        }
        public override String ToString()
        {
            String s = null;
            s += "Name  ";
            for (int i = 0; i < ndata; i++)
            {

                s += (name[i] + " ");
            }
            s += "Data  ";
            for (int i = 0; i < ndata; i++)
            {
                for (int j = 0; j < ndim; j++)
                {
                    s += (data[i, j].ToString() + " ");
                }
                s += "   ";
            }
            s += "Main Group  ";
            for (int i = 0; i < ndata; i++)
            {
               
                s += (mainGroup[i, 0].ToString() + " ");
            }
           
            return s;
        }
        public void standardize()
        {
            double[,] newData = new double[ndata, ndim];
            MWNumericArray MWdata = (MWNumericArray)data;
            MWNumericArray MWnewData = null;
            MWPreprocess.Transformation trsf = new Transformation();
            MWnewData = (MWNumericArray)trsf.standardization(MWdata);
            newData = (double[,])MWnewData.ToArray(MWArrayComponent.Real);
            data = newData;
        }
        public void logTransformation()
        {
            double[,] newData = new double[ndata, ndim];
            MWNumericArray MWdata = (MWNumericArray)data;
            MWNumericArray MWnewData = null;
            MWPreprocess.Transformation trsf = new Transformation();
            MWnewData = (MWNumericArray)trsf.logtransformation(MWdata);
            newData = (double[,])MWnewData.ToArray(MWArrayComponent.Real);
            data = newData;
        }
        public void logTransformation(double baseNum)
        {
            double[,] newData = new double[ndata, ndim];
            MWNumericArray MWdata = (MWNumericArray)data;
            MWNumericArray MWnewData = null;
            MWPreprocess.Transformation trsf = new Transformation();
            MWnewData = (MWNumericArray)trsf.logxtransformation(MWdata,baseNum);
            newData = (double[,])MWnewData.ToArray(MWArrayComponent.Real);
            data = newData;
        }
        public double[][,] KMeans(int clusterNum, String distType, String startType)
        {
            double[,] idc = new double[ndata, 1];
            double[,] centroid = new double[clusterNum, ndim];
            MWNumericArray MWdata = (MWNumericArray)data;
            MWArray[] MWoutput = null;
            MWDataMining.Cluster clust = new Cluster();
            MWoutput = clust.integratekmeans(2, MWdata, clusterNum, distType, startType);
            MWNumericArray MWidc = (MWNumericArray)MWoutput[0];
            MWNumericArray MWcentroid = (MWNumericArray)MWoutput[1];
            idc = (double[,])MWidc.ToArray(MWArrayComponent.Real);
            centroid = (double[,])MWcentroid.ToArray(MWArrayComponent.Real);
            double[][,] outfinal = new double[2][,];
            outfinal[0] = idc;
            outfinal[1] = centroid;
            return outfinal;
        }
        public double[,] som(int clstNumLength, int clstNumWedth, String topologyType, String distanceType)
        {
            double[,] idc = new double[ndata, 1];
            MWNumericArray MWdata = (MWNumericArray)data;
            MWNumericArray MWidc = null;
            MWDataMining.Cluster clust = new Cluster();
            MWidc = (MWNumericArray)clust.som(MWdata, clstNumLength, clstNumWedth, topologyType, distanceType);
            idc = (double[,])MWidc.ToArray(MWArrayComponent.Real);
            return idc;
        }
        public double[][,] gmm(int clusterNum,String modelType,int trainNum)
        {
            double[][,] outfinal = new double[2][,];
            double[,] idc = new double[ndata, 1];
            double[,] bic = new double[clusterNum, 1];
            MWNumericArray MWdata = (MWNumericArray)data;
            MWArray[] MWoutput = null;
            MWDataMining.Cluster clust = new Cluster();
            MWoutput = clust.integrategmm(2, MWdata, clusterNum, modelType, trainNum);
            MWNumericArray MWidc = (MWNumericArray)MWoutput[0];
            MWNumericArray MWbic = (MWNumericArray)MWoutput[1];
            idc = (double[,])MWidc.ToArray(MWArrayComponent.Real);
            bic = (double[,])MWbic.ToArray(MWArrayComponent.Real);
            outfinal[0] = idc;
            outfinal[1] = bic; //bic[0.0]为BIC值
            return outfinal;
        }
        public double[,] hierarchical(int clusterNum, String linkType, String distType)
        {
            double[,] idc = new double[ndata, 1];
            MWNumericArray MWdata = (MWNumericArray)data;
            MWNumericArray MWidc = null;
            MWDataMining.Cluster clust = new Cluster();
            MWidc = (MWNumericArray)clust.hierarchical(MWdata, clusterNum, linkType, distType);
            idc = (double[,])MWidc.ToArray(MWArrayComponent.Real);
            return idc;
        }
        public double[][,] fcm(int clusterNum, int trainNum)
        {
            double[,] idc = new double[ndata, 1];
            double[,] centroid = new double[clusterNum, ndim];
            MWNumericArray MWdata = (MWNumericArray)data;
            MWArray[] MWoutput = null;
            MWDataMining.Cluster clust = new Cluster();
            MWoutput = clust.integratefcm(2,MWdata,clusterNum,trainNum);
            MWNumericArray MWidc = (MWNumericArray)MWoutput[0];
            MWNumericArray MWcentroid = (MWNumericArray)MWoutput[1];
            idc = (double[,])MWidc.ToArray(MWArrayComponent.Real);
            centroid = (double[,])MWcentroid.ToArray(MWArrayComponent.Real);
            double[][,] outfinal = new double[2][,];
            outfinal[0] = idc;
            outfinal[1] = centroid;
            return outfinal;
        }
        public double[,] jackNife(int d)
        {
            double[,] newData = null ;
            if((d>=0) && (d<ndim))
            {
                newData = new double[ndata,ndim-1];
                for(int i=0; i<ndim; i++)
                {
                    if(i < d)
                    {
                        for(int j=0; j<ndata; j++)
                        {
                            newData[j,i] = data[j,i];
                        } 
                    }
                    if (i > d)
                    {
                        for (int j = 0; j < ndata; j++)
                        {
                            newData[j, i-1] = data[j, i];
                        } 
                    }
                }
                
            }
            return newData;
        }
        public double[,] JKMeans(int clusterNum, String distType, String startType)
        {
            double[,] idc = new double[ndata, ndim];
            for (int i = 0; i < ndim; i++)
            {
                double[,] curData = jackNife(i);
                MWNumericArray MWdata = (MWNumericArray)curData;
                MWArray[] MWoutput = null;
                MWDataMining.Cluster clust = new Cluster();
                MWoutput = clust.integratekmeans(2, MWdata, clusterNum, distType, startType);
                MWNumericArray MWidc = (MWNumericArray)MWoutput[0];
                double[,] idcTemp = (double[,])MWidc.ToArray(MWArrayComponent.Real);
                for (int j = 0; j < ndata; j++)
                {
                    idc[j, i] = idcTemp[j, 0];
                }
            }
            return idc;
        }
        public double[,] Jsom(int clstNumLength, int clstNumWedth, String topologyType, String distanceType)
        {
            double[,] idc = new double[ndata, ndim];
            for (int i = 0; i < ndim; i++)
            {
                double[,] curData = jackNife(i);
                MWNumericArray MWdata = (MWNumericArray)curData;
                MWDataMining.Cluster clust = new Cluster();
                MWNumericArray MWidc = (MWNumericArray)clust.som(MWdata, clstNumLength, clstNumWedth, topologyType, distanceType);
                double[,] idcTemp = (double[,])MWidc.ToArray(MWArrayComponent.Real);
                for (int j = 0; j < ndata; j++)
                {
                    idc[j, i] = idcTemp[j, 0];
                }
            }
            return idc;
        }
        public double[,] Jgmm(int clusterNum, String modelType, int trainNum)
        {
            double[,] idc = new double[ndata, ndim];
            for (int i = 0; i < ndim; i++)
            {
                double[,] curData = jackNife(i);
                MWNumericArray MWdata = (MWNumericArray)curData;
                MWArray[] MWoutput = null;
                MWDataMining.Cluster clust = new Cluster();
                MWoutput = clust.integrategmm(2, MWdata, clusterNum, modelType, trainNum);
                MWNumericArray MWidc = (MWNumericArray)MWoutput[0];
                double[,] idcTemp = (double[,])MWidc.ToArray(MWArrayComponent.Real);
                for (int j = 0; j < ndata; j++)
                {
                    idc[j, i] = idcTemp[j, 0];
                }
            }
            return idc;
        }
        public double[,] Jhierarchical(int clusterNum, String linkType, String distType)
        {
            double[,] idc = new double[ndata, ndim];
            for (int i = 0; i < ndim; i++)
            {
                double[,] curData = jackNife(i);
                MWNumericArray MWdata = (MWNumericArray)curData;
                MWDataMining.Cluster clust = new Cluster();
                MWNumericArray MWidc = (MWNumericArray)clust.hierarchical(MWdata, clusterNum, linkType, distType);
                double[,] idcTemp = (double[,])MWidc.ToArray(MWArrayComponent.Real);
                for (int j = 0; j < ndata; j++)
                {
                    idc[j, i] = idcTemp[j, 0];
                }
            }
            return idc;
        }
        public double[,] Jfcm(int clusterNum, int trainNum)
        {
            double[,] idc = new double[ndata, ndim];
            for (int i = 0; i < ndim; i++)
            {
                double[,] curData = jackNife(i);
                MWNumericArray MWdata = (MWNumericArray)curData;
                MWDataMining.Cluster clust = new Cluster();
                MWArray[] MWoutput = clust.integratefcm(2, MWdata, clusterNum, trainNum);
                MWNumericArray MWidc = (MWNumericArray)MWoutput[0];
                double[,] idcTemp = (double[,])MWidc.ToArray(MWArrayComponent.Real);
                for (int j = 0; j < ndata; j++)
                {
                    idc[j, i] = idcTemp[j, 0];
                }
            }
            return idc;
            
        }
        public double[][,] pca()
        {
            double[,] score = new double[ndata, ndim];
            double[,] pcvars = new double[ndim, 1];
            double[,] cumpcvars = new double[ndim, 1];
            double[][,] outfinal = new double[3][,];
            MWNumericArray MWdata = (MWNumericArray)data;
            MWArray[] MWoutput = null;
            MWPCA.PCA pcaf = new PCA();
            MWoutput = pcaf.pca(3,MWdata);
            MWNumericArray MWscore = (MWNumericArray)MWoutput[0];
            MWNumericArray MWpcvars = (MWNumericArray)MWoutput[1];
            MWNumericArray MWcumpcvars = (MWNumericArray)MWoutput[2];
            score = (double[,])MWscore.ToArray(MWArrayComponent.Real);
            pcvars = (double[,])MWpcvars.ToArray(MWArrayComponent.Real);
            cumpcvars = (double[,])MWcumpcvars.ToArray(MWArrayComponent.Real);
            outfinal[0] = score;
            outfinal[1] = pcvars;
            outfinal[2] = cumpcvars;
            return outfinal;
        }
        public double[,] silhouette(double[,] IDC,String distanceType)
        {
            double[,] s = new double[ndata, 1];
            MWNumericArray MWdata = (MWNumericArray)data;
            MWNumericArray MWIDC = (MWNumericArray)IDC;
            MWNumericArray MWs = null;
            MWDataMining.ClusterValidation clustVal = new ClusterValidation();
            MWs = (MWNumericArray)clustVal.integratesilhouette(MWdata, MWIDC, distanceType);
            s = (double[,])MWs.ToArray(MWArrayComponent.Real);
            return s;
        }
        public double ari(double[,] IDC, int clusterNum) //nclass不为0时才可以调用
        {
            MWNumericArray MWIDC = (MWNumericArray)IDC;
            MWNumericArray MWmainGroup = (MWNumericArray)mainGroup;
            MWNumericArray MWa = null;
            double[,] a = new double[1, 1];
            MWDataMining.ClusterValidation clustVal = new ClusterValidation();
            MWa = (MWNumericArray)clustVal.ari(MWIDC, MWmainGroup, clusterNum, nclass);
            a = (double[,])MWa.ToArray(MWArrayComponent.Real);
            return a[0,0];
        }
        public double afom(double[,] IDC, int clusterNum) //IDC为ndata*ndim
        {
            MWNumericArray MWIDC = (MWNumericArray)IDC;
            MWNumericArray MWdata = (MWNumericArray)data;
            MWNumericArray MWa = null;
            double[,] a = new double[1, 1];
            MWDataMining.ClusterValidation clustVal = new ClusterValidation();
            MWa = (MWNumericArray)clustVal.afom(MWdata, MWIDC, clusterNum);
            a = (double[,])MWa.ToArray(MWArrayComponent.Real);
            return a[0, 0];
        }
        public void knnImpute(int k, String distanceType)
        {
            MWNumericArray MWdata = (MWNumericArray)data;
            MWPreprocess.Impute impute = new Impute();
            MWNumericArray MWnewData = (MWNumericArray)impute.integrateknnimpute(MWdata, k, distanceType);
            double[,] newData = (double[,])MWnewData.ToArray(MWArrayComponent.Real);
            data = newData;
        }
        public void colAvgImpute(String avgType)
        {
            MWNumericArray MWdata = (MWNumericArray)data;
            MWPreprocess.Impute impute = new Impute();
            MWNumericArray MWnewData = (MWNumericArray)impute.colavgimpute(MWdata, avgType);
            double[,] newData = (double[,])MWnewData.ToArray(MWArrayComponent.Real);
            data = newData;
        }
        public void rowAvgImpute(String avgType)
        {
            MWNumericArray MWdata = (MWNumericArray)data;
            MWPreprocess.Impute impute = new Impute();
            MWNumericArray MWnewData = (MWNumericArray)impute.rowavgimpute(MWdata, avgType);
            double[,] newData = (double[,])MWnewData.ToArray(MWArrayComponent.Real);
            data = newData;
        }

        public void rowRemoveImpute()
        {
            MWNumericArray MWdata = (MWNumericArray)data;
            MWPreprocess.Filter filter = new Filter();
            MWArray[] MWoutput = filter.rowremoveimpute(2,MWdata);
            MWNumericArray MWnewData = (MWNumericArray)MWoutput[0];
            MWLogicalArray MWmask = (MWLogicalArray)MWoutput[1];
            double[,] newData = (double[,])MWnewData.ToArray(MWArrayComponent.Real);
            data = newData;
            ndata = newData.GetLength(0);
            ndim = newData.GetLength(1);
            if (name != null)
            {
                MWCharArray MWname = new MWCharArray(name);
                MWCharArray MWnewName = (MWCharArray)filter.rowremove((MWArray)MWname, MWmask);
                Array ArrNewName = MWnewName.ToArray();
                Char[,] chNewName = (Char[,])ArrNewName;
                int strNum = chNewName.GetLength(0);
                int strLen = chNewName.GetLength(1);
                String[] newName = new String[strNum];
                for (int i = 0; i < strNum; i++)
                {
                    Char[] ch = new Char[strLen];
                    for (int j = 0; j < strLen; j++)
                    {
                        ch[j] = chNewName[i, j];
                    }
                    newName[i] = new String(ch);
                }
                name = newName;
            }
            if (mainGroup != null)
            {
                MWNumericArray MWmainGroup = new MWNumericArray(mainGroup);
                MWNumericArray MWnewMainGroup = (MWNumericArray)filter.rowremove(MWmainGroup, MWmask);
                double[,] newMainGroup = (double[,])MWnewMainGroup.ToArray(MWArrayComponent.Real);
                mainGroup = newMainGroup;
            }
        }

        public void missingDataFilter(double prc)
        {
            MWNumericArray MWdata = (MWNumericArray)data;
            MWPreprocess.Filter filter = new Filter();
            MWArray[] MWoutput = filter.missingdatafilter(2, MWdata,prc);
            MWNumericArray MWnewData = (MWNumericArray)MWoutput[0];
            MWLogicalArray MWmask = (MWLogicalArray)MWoutput[1];
            double[,] newData = (double[,])MWnewData.ToArray(MWArrayComponent.Real);
            data = newData;
            ndata = newData.GetLength(0);
            ndim = newData.GetLength(1);
            if (name != null)
            {
                MWCharArray MWname = new MWCharArray(name);
                MWCharArray MWnewName = (MWCharArray)filter.rowremove((MWArray)MWname, MWmask);
                Array ArrNewName = MWnewName.ToArray();
                Char[,] chNewName = (Char[,])ArrNewName;
                int strNum = chNewName.GetLength(0);
                int strLen = chNewName.GetLength(1);
                String[] newName = new String[strNum];
                for (int i = 0; i < strNum; i++)
                {
                   Char[] ch = new Char[strLen];
                   for(int j = 0; j < strLen; j++)
                   {
                       ch[j] = chNewName[i, j];
                   }
                   newName[i] = new String(ch);
                }
                name = newName;
            }
            if (mainGroup != null)
            {
                MWNumericArray MWmainGroup = new MWNumericArray(mainGroup);
                MWNumericArray MWnewMainGroup = (MWNumericArray)filter.rowremove(MWmainGroup, MWmask);
                double[,] newMainGroup = (double[,])MWnewMainGroup.ToArray(MWArrayComponent.Real);
                mainGroup = newMainGroup;
            }
        }

        public void emptyFilter()
        {
            MWNumericArray MWdata = (MWNumericArray)data;
            MWCharArray MWchName = new MWCharArray(name);
            MWCellArray MWname = new MWCellArray(MWchName);
            MWPreprocess.Filter filter = new Filter();
            MWArray[] MWoutput = filter.emptyremove(3, MWdata, MWname);
            MWNumericArray MWnewData = (MWNumericArray)MWoutput[0];
            MWCellArray MWnewName = (MWCellArray)MWoutput[1];
            MWLogicalArray MWmask = (MWLogicalArray)MWoutput[2];
            int stringNum = MWnewName.NumberOfElements;
            String[] newName = new String[stringNum];
            for (int i = 1; i <= stringNum; i++)
            {
                MWArray MWarrNewName = MWnewName[i];
                newName[i-1] = MWarrNewName.ToString();
            }
            name = newName;
            double[,] newData = (double[,])MWnewData.ToArray(MWArrayComponent.Real);
            data = newData;
            ndata = newData.GetLength(0);
            ndim = newData.GetLength(1);
            if (mainGroup != null)
            {
                MWNumericArray MWmainGroup = new MWNumericArray(mainGroup);
                MWNumericArray MWnewMainGroup = (MWNumericArray)filter.rowremove(MWmainGroup, MWmask);
                double[,] newMainGroup = (double[,])MWnewMainGroup.ToArray(MWArrayComponent.Real);
                mainGroup = newMainGroup;
            }
        }

        public void absFilter(double abscutoff,int num)
        {
            MWNumericArray MWdata = (MWNumericArray)data;
            MWPreprocess.Filter filter = new Filter();
            MWArray[] MWoutput = filter.absfilter(2, MWdata, abscutoff, num);
            MWNumericArray MWnewData = (MWNumericArray)MWoutput[0];
            MWLogicalArray MWmask = (MWLogicalArray)MWoutput[1];
            double[,] newData = (double[,])MWnewData.ToArray(MWArrayComponent.Real);
            data = newData;
            ndata = newData.GetLength(0);
            ndim = newData.GetLength(1);
            if (name != null)
            {
                MWCharArray MWname = new MWCharArray(name);
                MWCharArray MWnewName = (MWCharArray)filter.rowremove((MWArray)MWname, MWmask);
                Array ArrNewName = MWnewName.ToArray();
                Char[,] chNewName = (Char[,])ArrNewName;
                int strNum = chNewName.GetLength(0);
                int strLen = chNewName.GetLength(1);
                String[] newName = new String[strNum];
                for (int i = 0; i < strNum; i++)
                {
                    Char[] ch = new Char[strLen];
                    for (int j = 0; j < strLen; j++)
                    {
                        ch[j] = chNewName[i, j];
                    }
                    newName[i] = new String(ch);
                }
                name = newName;
            }
            if (mainGroup != null)
            {
                MWNumericArray MWmainGroup = new MWNumericArray(mainGroup);
                MWNumericArray MWnewMainGroup = (MWNumericArray)filter.rowremove(MWmainGroup, MWmask);
                double[,] newMainGroup = (double[,])MWnewMainGroup.ToArray(MWArrayComponent.Real);
                mainGroup = newMainGroup;
            }
        }

        public void rangeFilter(double range)
        {
            MWNumericArray MWdata = (MWNumericArray)data;
            MWPreprocess.Filter filter = new Filter();
            MWArray[] MWoutput = filter.rangefilter(2, MWdata, range);
            MWNumericArray MWnewData = (MWNumericArray)MWoutput[0];
            MWLogicalArray MWmask = (MWLogicalArray)MWoutput[1];
            double[,] newData = (double[,])MWnewData.ToArray(MWArrayComponent.Real);
            data = newData;
            ndata = newData.GetLength(0);
            ndim = newData.GetLength(1);
            if (name != null)
            {
                MWCharArray MWname = new MWCharArray(name);
                MWCharArray MWnewName = (MWCharArray)filter.rowremove((MWArray)MWname, MWmask);
                Array ArrNewName = MWnewName.ToArray();
                Char[,] chNewName = (Char[,])ArrNewName;
                int strNum = chNewName.GetLength(0);
                int strLen = chNewName.GetLength(1);
                String[] newName = new String[strNum];
                for (int i = 0; i < strNum; i++)
                {
                    Char[] ch = new Char[strLen];
                    for (int j = 0; j < strLen; j++)
                    {
                        ch[j] = chNewName[i, j];
                    }
                    newName[i] = new String(ch);
                }
                name = newName;
            }
            if (mainGroup != null)
            {
                MWNumericArray MWmainGroup = new MWNumericArray(mainGroup);
                MWNumericArray MWnewMainGroup = (MWNumericArray)filter.rowremove(MWmainGroup, MWmask);
                double[,] newMainGroup = (double[,])MWnewMainGroup.ToArray(MWArrayComponent.Real);
                mainGroup = newMainGroup;
            }
        }

        public void varFilter(double var)
        {
            MWNumericArray MWdata = (MWNumericArray)data;
            MWPreprocess.Filter filter = new Filter();
            MWArray[] MWoutput = filter.varfilter(2, MWdata, var);
            MWNumericArray MWnewData = (MWNumericArray)MWoutput[0];
            MWLogicalArray MWmask = (MWLogicalArray)MWoutput[1];
            double[,] newData = (double[,])MWnewData.ToArray(MWArrayComponent.Real);
            data = newData;
            ndata = newData.GetLength(0);
            ndim = newData.GetLength(1);
            if (name != null)
            {
                MWCharArray MWname = new MWCharArray(name);
                MWCharArray MWnewName = (MWCharArray)filter.rowremove((MWArray)MWname, MWmask);
                Array ArrNewName = MWnewName.ToArray();
                Char[,] chNewName = (Char[,])ArrNewName;
                int strNum = chNewName.GetLength(0);
                int strLen = chNewName.GetLength(1);
                String[] newName = new String[strNum];
                for (int i = 0; i < strNum; i++)
                {
                    Char[] ch = new Char[strLen];
                    for (int j = 0; j < strLen; j++)
                    {
                        ch[j] = chNewName[i, j];
                    }
                    newName[i] = new String(ch);
                }
                name = newName;
            }
            if (mainGroup != null)
            {
                MWNumericArray MWmainGroup = new MWNumericArray(mainGroup);
                MWNumericArray MWnewMainGroup = (MWNumericArray)filter.rowremove(MWmainGroup, MWmask);
                double[,] newMainGroup = (double[,])MWnewMainGroup.ToArray(MWArrayComponent.Real);
                mainGroup = newMainGroup;
            }
        }

        public void entropyFilter(double prc)
        {
            MWNumericArray MWdata = (MWNumericArray)data;
            MWPreprocess.Filter filter = new Filter();
            MWArray[] MWoutput = filter.entropyfilter(2, MWdata, prc);
            MWNumericArray MWnewData = (MWNumericArray)MWoutput[0];
            MWLogicalArray MWmask = (MWLogicalArray)MWoutput[1];
            double[,] newData = (double[,])MWnewData.ToArray(MWArrayComponent.Real);
            data = newData;
            ndata = newData.GetLength(0);
            ndim = newData.GetLength(1);
            if (name != null)
            {
                MWCharArray MWname = new MWCharArray(name);
                MWCharArray MWnewName = (MWCharArray)filter.rowremove((MWArray)MWname, MWmask);
                Array ArrNewName = MWnewName.ToArray();
                Char[,] chNewName = (Char[,])ArrNewName;
                int strNum = chNewName.GetLength(0);
                int strLen = chNewName.GetLength(1);
                String[] newName = new String[strNum];
                for (int i = 0; i < strNum; i++)
                {
                    Char[] ch = new Char[strLen];
                    for (int j = 0; j < strLen; j++)
                    {
                        ch[j] = chNewName[i, j];
                    }
                    newName[i] = new String(ch);
                }
                name = newName;
            }
            if (mainGroup != null)
            {
                MWNumericArray MWmainGroup = new MWNumericArray(mainGroup);
                MWNumericArray MWnewMainGroup = (MWNumericArray)filter.rowremove(MWmainGroup, MWmask);
                double[,] newMainGroup = (double[,])MWnewMainGroup.ToArray(MWArrayComponent.Real);
                mainGroup = newMainGroup;
            }
        }
    }

}
